package org.example.config;

import org.apache.commons.lang3.StringUtils;
import org.example.utils.IpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;


/**
 * @author jingjing.zhang
 */
@WebFilter(filterName = "RequestAndResponseFilter", urlPatterns = "/*")
@Order(2)
public class RequestAndResponseFilter extends OncePerRequestFilter {
    private static final Logger logger = LoggerFactory.getLogger(RequestAndResponseFilter.class);
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        long startTime = System.currentTimeMillis();
        String path    = request.getQueryString();
        String method  = request.getMethod();
        String uri     = request.getRequestURI();
        String contextPath = request.getContextPath();
        String servletPath = request.getServletPath();

        RequestWrapper requestWrapper = null;
        StringBuilder sb = new StringBuilder();
        if (request instanceof HttpServletRequest) {
            requestWrapper = new RequestWrapper(request);
            BufferedReader bufferedReader = requestWrapper.getReader();
            String line;
            while ((line = bufferedReader.readLine()) != null) {
                sb.append(line);
            }
        }
        logger.info("[Api Access] start. \n uri:{}, contextPath:{}, servletPath: {}, method: {}, client: {}",
                uri,contextPath, servletPath, method, IpUtils.getIP(request));
        logger.info("[Api Access] request params: \n{}", StringUtils.isBlank(path)?sb.toString():path);

        ResponseWrapper responseWrapper=new ResponseWrapper(response);
        if (null == requestWrapper) {
            filterChain.doFilter(request, response);
        } else {
            filterChain.doFilter(requestWrapper, responseWrapper);
        }

        String result=new String(responseWrapper.getResponseData());
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(result.getBytes());
        outputStream.flush();
        outputStream.close();
        // 打印response
        logger.info("[Api Access] response data: \n{}", result);
        logger.info("[Api Access] end. \n uri:{}, contextPath:{}, servletPath: {},method: {}, client: {}, duration: {}ms",
                uri,contextPath, servletPath, method, IpUtils.getIP(request),System.currentTimeMillis() - startTime);
    }
}
